/*
* ============================================================================
*  Name        : example_101.cpp
*  Part of     : Finite state machine examples
*  Description :
*  Version     : %version: %
*  
*
* ============================================================================
*/
#include "example_101.h"

/**
 * @file example_101.cpp
 *
 * @details
 * Example of complex associations
 *
 * @ingroup AssociationExamples
 */
using namespace sea_examples;

// ----------------------------------------------------------------------------
// Objects associations... 
// @ingroup AssociationExamples
// ----------------------------------------------------------------------------
void sea_examples::launch_example_101( )
{
    SEA_TRACE_ENTRY( );

    // People
    aref Tom( "Tom" );
    aref John( "John" );
    aref Kate( "Kate" );

    // Some attributes/associations
    aref marriage( "married" );
    aref co_worker( "co-worker" );
    aref human( "human" );

    // Lets connect them. There is a notion who is on the right 
    // and who is on the left... It is up to the application
    // how to treat such a knowledge - either as time (before/after),
    // relative location or hierarchy
    Tom->attach_left_of( Kate, marriage );
    Tom->attach_left_of( Kate, human );
    
    John->attach_left_of( Kate, co_worker );
    John->attach_left_of( Kate, human );

    John->attach_left_of( Tom, human );

    // Lets list all of the connections
    SEA_TRACE( "\n %s is related to:", Tom->as< char >( ) );
    for( VIterator< > i( Tom ); *i; i++ ) SEA_TRACE( "   %s as %s", i->as< char >( ), i.by< char >( ) );

    SEA_TRACE( "\n %s is related to:", John->as< char >( ) );
    for( VIterator< > i( John ); *i; i++ ) SEA_TRACE( "   %s as %s", i->as< char >( ), i.by< char >( ) );

    SEA_TRACE( "\n %s is related to:", Kate->as< char >( ) );
    for( VIterator< Object, Left > i( Kate ); *i; i++ ) SEA_TRACE( "   %s as %s", i->as< char >( ), i.by< char >( ) );

    // Breaking all. Notice that Kate will be alone - with no
    // associations if both guys break the links...
    Tom->detach_all( );
    John->detach_all( );
    // Kate->detach_all( );
}

// ----------------------------------------------------------------------------
// Objects associations... Qualities/attributes
// @ingroup AssociationExamples
// ----------------------------------------------------------------------------
void sea_examples::launch_example_102( )
{
    SEA_TRACE_ENTRY( );

    {
        // An object
        aref apple( "apple" );

        // Objects qualities
        aref color( "color" );
        aref smell( "smell" );

        // More quality details
        aref red( "red" );
        aref yellow( "yellow" );

        // color includes red and yellow
        color += red;
        color += yellow;

        // List colors
        for( VIterator< Object, Either > it( color ); *it; it++ )
        {
            SEA_TRACE( " Color has %s", it->as< char >( ) );
        }

        // Adding apple attributes
        apple += color; // OR apple->has( color );
        apple += smell; // OR apple->has( smell );

        if ( apple( color ) == true )
        {
            SEA_TRACE( "Apple has color");
        }

        if ( apple( smell ) == true )
        {
            SEA_TRACE( "Apple has smell");
        }

        // List them
        for( VIterator< Object, Either > it( apple ); *it; it++ )
        {
            SEA_TRACE( " %s has %s", apple->as< char >( ), it->as< char >( ) );
        }

        // Apple doesnt smell or has no color
        apple -= color; // OR apple->has_no( color );
        apple -= smell; // OR apple->has_no( smell );

        if ( !apple( color ) )
        {
            SEA_TRACE( "Apple has no color");
        }

        if ( !apple( smell ) )
        {
            SEA_TRACE( "Apple has no smell");
        }

        // Remove all attributes
        color->detach_all( );
    }

    SEA_MEM_LEAKS( );
}

// ----------------------------------------------------------------------------
